package com.wg.core.script;

import java.util.EnumMap;
import java.util.Objects;

/**
 * 脚本参数容器，提供类型安全的参数存取能力
 * <p>
 * 基于枚举键（Key）管理参数，避免字符串键的拼写错误
 * </p>
 *
 * @author 少爷123
 */
public class ScriptArgs {

    private final EnumMap<Key, Object> args = new EnumMap<>(Key.class);

    public ScriptArgs() {
    }

    /**
     * 类型安全获取参数
     *
     * @param key   参数键（不可为null）
     * @param clazz 目标类型（不可为null）
     * @param <T>   目标类型
     * @return 参数值（若键不存在或类型不匹配则返回null）
     */
    public <T> T get(Key key, Class<T> clazz) {
        Objects.requireNonNull(key, "key cannot be null");
        Objects.requireNonNull(clazz, "clazz cannot be null");
        Object value = args.get(key);
        return clazz.isInstance(value) ? clazz.cast(value) : null;
    }

    /**
     * 快捷获取Player对象
     *
     * @param <T> Player类型
     * @return Player实例（类型不匹配返回null）
     */
    @SuppressWarnings("unchecked")
    public <T> T getPlayer() {
        return (T) get(Key.PLAYER);
    }

    /**
     * 快捷获取请求上下文
     *
     * @param <T> Request类型
     * @return Request实例（类型不匹配返回null）
     */
    @SuppressWarnings("unchecked")
    public <T> T getRequest() {
        return (T) get(Key.REQUEST);
    }

    /**
     * 原始类型获取（需自行确保类型兼容，可能抛ClassCastException）
     *
     * @param key 参数键（不可为null）
     * @param <T> 目标类型
     * @return 参数值（键不存在返回null）
     */
    @SuppressWarnings("unchecked")
    public <T> T get(Key key) {
        return (T) args.get(Objects.requireNonNull(key, "key cannot be null"));
    }

    /**
     * 添加参数（值不可为null）
     *
     * @param key   参数键（不可为null）
     * @param value 参数值（不可为null）
     * @throws NullPointerException 若key或value为null
     */
    public void put(Key key, Object value) {
        args.put(
                Objects.requireNonNull(key, "key cannot be null"),
                Objects.requireNonNull(value, "value cannot be null for key: " + key));
    }

    /**
     * 清空所有参数
     */
    public void clear() {
        args.clear();
    }

    /**
     * 参数键枚举（预定义常用参数类型）
     */
    public enum Key {
        /**
         * 玩家对象（如User、Player实体类）
         */
        PLAYER,
        /**
         * 对端连接对象（如Socket、Channel）
         */
        PEER,
        /**
         * 请求上下文（如HttpServletRequest、自定义Request对象）
         */
        REQUEST,
        /**
         * 通用参数1（业务自定义用途）
         */
        ARG1,
        /**
         * 通用参数2（业务自定义用途）
         */
        ARG2,
        /**
         * 通用参数3（业务自定义用途）
         */
        ARG3,
        /**
         * 通用参数4（业务自定义用途）
         */
        ARG4,
        /**
         * 通用参数5（业务自定义用途）
         */
        ARG5,
        /**
         * 扩展上下文（复杂业务场景的自定义对象容器）
         */
        CONTEXT
    }
}